// searchAPI.js - 智能搜题模块 API 接口

// 基础 API URL 配置
// 可以通过uni.getStorageSync('apiBaseUrl')读取自定义配置
// 或者读取环境变量等方式动态配置
function getApiBaseUrl() {
  try {
    // 尝试从本地存储读取自定义API地址
    const customUrl = uni.getStorageSync('doubaoApiBaseUrl');
    if (customUrl) return customUrl;
    
    // 默认API地址
    // 根据不同环境返回不同的API地址
    // #ifdef H5
    return 'http://localhost:8848/api/doubao'; // 开发环境H5
    // #endif
    
    // #ifdef MP-WEIXIN
    // 使用合法的域名，不要使用不可解析的域名
    return 'http://localhost:8848/api/doubao'; // 开发环境下使用本地测试服务器
    // return 'https://example.com/api/doubao'; // 生产环境应使用真实域名
    // #endif
    
    // 其他环境
    return 'http://localhost:8848/api/doubao'; // 默认使用本地测试服务器
  } catch (e) {
    console.error('获取API地址失败:', e);
    return 'http://localhost:8848/api/doubao';
  }
}

/**
 * 基于文本进行搜题查询
 * @param {string} question 问题文本
 * @param {Function} onStreamData 流式数据回调函数
 * @param {string} [systemPrompt] 可选的系统提示，已不再使用
 * @param {string} [model=null] 模型名称，已不再使用
 * @returns {Promise<Object>} 结果对象
 */
export function searchQuestionByText(question, onStreamData, systemPrompt, model = null) {
  const API_BASE_URL = getApiBaseUrl();
  
  return new Promise((resolve, reject) => {
    // 后端只需要原始问题文本，不再需要复杂的请求体结构
    const questionText = question.trim();
    
    if (!questionText) {
      reject({ success: false, message: '问题不能为空' });
      return;
    }
    
    // 使用uni.request替代XMLHttpRequest
    uni.request({
      url: `${API_BASE_URL}/chat`,
      method: 'POST',
      data: questionText, // 直接发送问题文本
      dataType: 'text', // 期望接收纯文本响应
      responseType: 'text',
      header: {
        'Content-Type': 'application/json'
      },
      // 增加超时时间到90秒
      timeout: 90000,
      success: (res) => {
        if (res.statusCode >= 200 && res.statusCode < 300) {
          try {
            // 检查响应是否为JSON错误消息
            let content = res.data;
            let isError = false;
            
            try {
              // 尝试解析为JSON，检查是否包含错误信息
              const jsonData = JSON.parse(content);
              if (jsonData.code && jsonData.code !== 200) {
                content = jsonData.message || '处理问题时出错';
                isError = true;
                console.error('服务器返回错误:', jsonData);
              }
            } catch (e) {
              // 不是JSON，当作正常响应处理
            }
            
            // 如果提取到内容，调用回调函数
            if (content && onStreamData) {
              if (isError) {
                onStreamData('处理失败: ' + content);
              } else {
                onStreamData(content);
              }
            } else if (onStreamData) {
              // 如果没有提取到内容，返回错误信息
              onStreamData('未能获取有效的回答，请重试');
            }
            
            resolve({
              success: !isError,
              content: content,
              fullData: res.data
            });
          } catch (error) {
            console.error('处理响应数据时出错:', error);
            
            // 即使解析失败，也尝试返回原始响应
            if (onStreamData && res.data) {
              onStreamData(res.data);
            }
            
            resolve({
              success: false,
              content: '处理响应时出错',
              fullData: res.data
            });
          }
        } else {
          // 请求状态码异常
          let errorMsg = '请求失败';
          try {
            // 尝试从响应中提取错误信息
            const errData = JSON.parse(res.data);
            if (errData.message) {
              errorMsg = errData.message;
            }
          } catch (e) {
            // 解析失败，使用默认错误消息
          }
          
          if (onStreamData) {
            onStreamData('请求失败: ' + errorMsg);
          }
          
          reject({
            success: false,
            status: res.statusCode,
            message: errorMsg,
            data: res.data
          });
        }
      },
      fail: (err) => {
        console.error('API请求失败:', err);
        
        let errorMessage = '网络请求失败';
        if (err.errMsg && err.errMsg.includes('timeout')) {
          errorMessage = '请求超时，请稍后再试';
        }
        
        if (onStreamData) {
          onStreamData('请求失败: ' + errorMessage);
        }
        
        // 请求失败
        reject({
          success: false,
          message: errorMessage,
          error: err
        });
      }
    });
  });
}

/**
 * 预处理图片，优化识别效果
 * @param {string} imagePath 图片路径
 * @returns {Promise<{path: string, size: number}>} 处理后的图片信息
 */
async function preprocessImage(imagePath) {
  try {
    // 获取图片信息
    const imageInfo = await new Promise((resolve, reject) => {
      uni.getImageInfo({
        src: imagePath,
        success: resolve,
        fail: reject
      });
    });

    console.log('原始图片信息:', imageInfo);
    
    // 获取图片大小信息
    const fileInfo = await new Promise((resolve, reject) => {
      uni.getFileInfo({
        filePath: imagePath,
        success: resolve,
        fail: reject
      });
    });
    
    // 如果图片小于 800KB 且尺寸适中，无需处理
    if (fileInfo.size < 800 * 1024 && imageInfo.width <= 1600 && imageInfo.height <= 1600) {
      console.log('图片大小适中，无需压缩');
      return { path: imagePath, size: fileInfo.size };
    }
    
    // 压缩图片
    console.log('开始压缩图片...');
    
    // 计算压缩参数
    let quality = 80; // 默认质量
    if (fileInfo.size > 3 * 1024 * 1024) { // 大于3MB
      quality = 60;
    } else if (fileInfo.size > 1.5 * 1024 * 1024) { // 大于1.5MB
      quality = 70;
    }
    
    // 使用微信压缩API
    const compressResult = await new Promise((resolve, reject) => {
      uni.compressImage({
        src: imagePath,
        quality,
        success: resolve,
        fail: reject
      });
    });
    
    // 获取压缩后图片的大小信息
    const compressedFileInfo = await new Promise((resolve, reject) => {
      uni.getFileInfo({
        filePath: compressResult.tempFilePath,
        success: resolve,
        fail: reject
      });
    });
    
    console.log('压缩后图片大小:', compressedFileInfo.size);
    
    return {
      path: compressResult.tempFilePath,
      size: compressedFileInfo.size
    };
  } catch (error) {
    console.error('图片预处理失败:', error);
    // 预处理失败时返回原图信息
    return { path: imagePath, size: 0 };
  }
}

/**
 * 优化图片提示，针对特定场景
 * @param {string} imageType 图片类型或场景 
 * @returns {string} 优化后的系统提示
 */
function getOptimizedPrompt(imageType = 'default') {
  const basePrompt = "你是一个专业的图像识别和题目解答助手，擅长解读图片中的所有文字内容。请尽可能准确地识别图片中的所有文字，并根据上下文判断这可能是一个什么样的问题。";
  
  // 不同场景的提示优化
  const promptTypes = {
    'default': basePrompt + "即使图片质量不佳或文字模糊，也请尽力解读出最可能的内容。识别出文字后，作为题目解答助手，请分析题目并给出详细解答。",
    'math': basePrompt + "这是一道数学题。请特别注意识别数学公式、符号和数字，确保它们被正确解读。然后，请详细解答这道数学题目，给出完整的解题步骤和最终答案。",
    'text': basePrompt + "这是一道文字题。请完整识别所有文字内容，并确保段落和句子的完整性。然后，请解答这个问题，给出详细的分析和答案。",
    'code': basePrompt + "这是一道编程或算法题。请准确识别代码片段、算法描述和问题要求，确保符号和缩进正确。然后，分析这个编程问题并给出解决方案，提供代码实现或算法思路。"
  };
  
  return promptTypes[imageType] || promptTypes['default'];
}

/**
 * 基于图片进行搜题查询
 * @param {Object} imageFile 图片文件对象（通过 uni.chooseImage 获取）
 * @param {Function} onStreamData 流式数据回调函数
 * @param {string} [systemPrompt] 可选的系统提示，已不再使用
 * @param {string} [imageType='default'] 图片类型，仅前端分类使用
 * @param {string} [model=null] 模型名称，已不再使用
 * @param {string} [userQuestion=''] 用户提出的问题
 * @returns {Promise<Object>} 结果对象
 */
export function searchQuestionByImage(imageFile, onStreamData, systemPrompt, imageType = 'default', model = null, userQuestion = '') {
  const API_BASE_URL = getApiBaseUrl();
  
  return new Promise(async (resolve, reject) => {
    try {
      if (!imageFile || !imageFile.path) {
        reject({ success: false, message: '图片文件无效' });
        return;
      }
      
      // 预处理回调
      if (onStreamData) {
        onStreamData('正在处理图片，优化识别效果...');
      }
      
      // 预处理图片，优化识别效果
      const processedImage = await preprocessImage(imageFile.path);
      console.log('图片预处理完成:', processedImage);
      
      if (onStreamData) {
        onStreamData('图片处理完成，开始识别内容...\n请耐心等待，图片处理通常需要10-60秒');
      }
      
      // 构建用户问题，如果有提供就使用，否则使用默认问题
      const question = userQuestion.trim() ? 
                     userQuestion : 
                     "请识别并解答图片中的题目，尽量提取所有可见的文字。如果图片质量不佳，请尽力辨识。";
      
      console.log('开始上传图片:', processedImage.path);
      console.log('用户问题:', question);
      
      // 使用uni.uploadFile替代FormData和XMLHttpRequest
      // 注意：这里更新参数名，与后端接口匹配
      const uploadTask = uni.uploadFile({
        url: `${API_BASE_URL}/chat-with-image`,
        filePath: processedImage.path,
        name: 'imageUrl', // 更新为后端接口需要的参数名
        formData: {
          question: question
        },
        // 增加超时时间到6分钟 (360秒)，与服务器端处理时间匹配
        timeout: 360000,
        success: (uploadRes) => {
          console.log('图片上传响应状态:', uploadRes.statusCode);
          
          if (uploadRes.statusCode >= 200 && uploadRes.statusCode < 300) {
            try {
              console.log('处理图片上传响应');
              
              // 检查响应是否为JSON错误消息
              let content = uploadRes.data;
              let isError = false;
              
              try {
                // 尝试解析为JSON，检查是否包含错误信息
                const jsonData = JSON.parse(content);
                if (jsonData.code && jsonData.code !== 200) {
                  content = jsonData.message || '处理图片时出错';
                  isError = true;
                  console.error('服务器返回错误:', jsonData);
                }
              } catch (e) {
                // 不是JSON，当作正常响应处理
              }
              
              // 调用回调函数
              if (content && onStreamData) {
                if (isError) {
                  onStreamData('图片处理失败: ' + content);
                } else {
                  onStreamData(content);
                }
                console.log('成功调用onStreamData回调');
              } else if (onStreamData) {
                // 如果没提取到内容，返回错误信息
                onStreamData('无法获取有效的响应内容，请重试');
                console.log('没有获取到有效内容');
              }
              
              resolve({
                success: !isError,
                content: content,
                fullData: uploadRes.data
              });
            } catch (error) {
              console.error('处理图片搜题响应时出错:', error);
              
              // 即使处理失败，也尝试返回原始数据
              if (onStreamData) {
                onStreamData('图片识别过程中出现错误，请重新上传更清晰的图片，或使用文本搜题功能。');
              }
              
              resolve({
                success: false,
                content: '处理响应时出错',
                fullData: uploadRes.data
              });
            }
          } else {
            console.error('图片搜题请求失败:', uploadRes.statusCode, uploadRes.errMsg);
            let errorMsg = '图片上传请求失败';
            try {
              // 尝试从响应中提取错误信息
              const errData = JSON.parse(uploadRes.data);
              if (errData.message) {
                errorMsg = errData.message;
              }
            } catch (e) {
              // 解析失败，使用默认错误消息
            }
            
            if (onStreamData) {
              onStreamData('请求失败: ' + errorMsg);
            }
            
            reject({
              success: false,
              status: uploadRes.statusCode,
              message: errorMsg,
              data: uploadRes.data
            });
          }
        },
        fail: (err) => {
          console.error('图片上传失败:', err);
          
          // 提供更详细的错误信息
          let errorMessage = '图片上传失败';
          if (err.errMsg && err.errMsg.includes('timeout')) {
            errorMessage = '图片上传超时，请尝试以下解决方案：\n1. 检查网络连接\n2. 使用更小的图片\n3. 确保服务器正常运行\n4. 重试上传';
          }
          
          if (onStreamData) {
            onStreamData('上传失败: ' + errorMessage);
          }
          
          reject({
            success: false,
            message: errorMessage,
            error: err
          });
        }
      });
      
      // 添加上传进度监听
      if (uploadTask && uploadTask.onProgressUpdate) {
        uploadTask.onProgressUpdate((res) => {
          if (onStreamData && res.progress > 0) {
            const progressMessage = `图片上传进度: ${res.progress}%`;
            if (res.progress < 100) {
              onStreamData(`正在上传图片... ${res.progress}%\n请耐心等待，图片识别通常需要10-60秒`);
            }
            console.log(progressMessage);
          }
        });
      }
    } catch (error) {
      console.error('图片搜索准备阶段出错:', error);
      reject({
        success: false,
        message: '图片处理失败: ' + (error.message || '未知错误'),
        error: error
      });
    }
  });
}

/**
 * 将小程序本地文件路径转换为Base64（如需使用）
 * @param {string} filePath 文件路径
 * @returns {Promise<string>} Base64字符串
 */
function filePathToBase64(filePath) {
  return new Promise((resolve, reject) => {
    uni.getFileSystemManager().readFile({
      filePath: filePath,
      encoding: 'base64',
      success: res => {
        resolve(res.data);
      },
      fail: err => {
        reject(err);
      }
    });
  });
}

/**
 * 保存搜题历史记录
 * @param {Array} historyArray 历史记录数组
 */
export function saveSearchHistory(historyArray) {
  try {
    uni.setStorageSync('searchQuestionsHistory', JSON.stringify(historyArray));
  } catch (error) {
    console.error('保存搜题历史失败:', error);
  }
}

/**
 * 获取搜题历史记录
 * @returns {Array} 历史记录数组
 */
export function getSearchHistory() {
  try {
    const history = uni.getStorageSync('searchQuestionsHistory');
    return history ? JSON.parse(history) : [];
  } catch (error) {
    console.error('获取搜题历史失败:', error);
    return [];
  }
}

/**
 * 清空搜题历史记录
 */
export function clearSearchHistory() {
  try {
    uni.removeStorageSync('searchQuestionsHistory');
  } catch (error) {
    console.error('清空搜题历史失败:', error);
  }
}

/**
 * 设置智能搜题API基础地址
 * @param {string} url API基础地址
 */
export function setSearchApiBaseUrl(url) {
  if (!url) return false;
  
  try {
    uni.setStorageSync('doubaoApiBaseUrl', url);
    return true;
  } catch (e) {
    console.error('设置API地址失败:', e);
    return false;
  }
}

/**
 * 重置智能搜题API地址为默认值
 */
export function resetSearchApiBaseUrl() {
  try {
    uni.removeStorageSync('doubaoApiBaseUrl');
    return true;
  } catch (e) {
    console.error('重置API地址失败:', e);
    return false;
  }
} 